package com.kungfuhacking.wristbandpro.mqtt;

import android.app.ActivityManager;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Environment;
import android.os.Vibrator;
import android.support.annotation.NonNull;
import android.util.Log;

import com.alibaba.fastjson.JSONObject;
import com.kungfuhacking.wristbandpro.R;
import com.kungfuhacking.wristbandpro.base.view.HomeActivity;
import com.kungfuhacking.wristbandpro.database.DatabaseManager;
import com.kungfuhacking.wristbandpro.mqtt.bean.MessageBean;
import com.kungfuhacking.wristbandpro.net.RetrofitHttpUtil;
import com.kungfuhacking.wristbandpro.utils.CommonUtils;
import com.kungfuhacking.wristbandpro.utils.Constant;
import com.kungfuhacking.wristbandpro.utils.File2Code;

import org.greenrobot.eventbus.EventBus;
import org.json.JSONException;

import java.io.File;
import java.io.IOException;
import java.util.Set;
import java.util.UUID;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;


/**
 * 聊天消息处理类
 * Created by Aaron on 16/3/25.
 */
public class ChatMessageManager {

    private Context ctx;
    private SharedPreferences sp;
    private int loadId;
    private SoundPool soundPool;
    private Vibrator vibrator;
    private String TAG = getClass().getSimpleName();

    private ChatMessageManager() {
    }

    private static ChatMessageManager cm = new ChatMessageManager();

    public static ChatMessageManager getInstance() {
        return cm;
    }

    /**
     * 处理消息
     *
     * @param topic
     * @param message
     */
    public void handlerMessage(String topic, String message, Context ctx) {

        try {

            this.ctx = ctx;
            if (sp == null)
                sp = ctx.getSharedPreferences(Constant.CONFIG, Context.MODE_PRIVATE);

//            Log.d(TAG, " 收到消息的topic : " + topic);

//        //判断出消息类型
//        int chatType = getChatType(topic);

//**************************************************系统消息**********************************************************************//

            if (topic.startsWith(MqttConstant.START_SYSTEM))
                handleSystemMessage(message);

            else
//**************************************************聊天消息**********************************************************************//

                handleChatMessage(topic, message);

        } catch (Exception e) {
            Log.e(TAG, "接受消息出现了问题 消息:" + message);
        }

    }

    /**
     * 处理系统消息
     *
     * @param message 聊天的消息
     * @throws JSONException
     */
    private void handleSystemMessage(String message) throws JSONException {
        //系统消息
        org.json.JSONObject js = new org.json.JSONObject(message);

        String order = js.getString("order");
        String mTopic = js.getString("topic");

        if (MqttConstant.SUB.equals(order)) {   //订阅主题

            js = new org.json.JSONObject(mTopic);
//            updateInfo(js.getString("topic"), js.getString("topicImg"), js.getString("topicName"));
            //关注老人圈，
            MqttManager.getInstance().subTopicSingle(js.getString("topic"));
            //topic表中插入数据
            DatabaseManager.getInstance().insertEmptyContent(ctx, js.getString("topic"), js.getString("topicName"),
                    js.getString("topicImg"), sp.getString(MqttConstant.USERID, ""));

            Log.e(TAG, "系统消息: 订阅主题 : topic:" + js.getString("topic"));

        } else if (MqttConstant.UN_SUB.equals(order)) {     //取消订阅主题
            Log.e(TAG, "系统消息: 取消订阅 : topic:" + mTopic);
            MqttManager.getInstance().unSubTopic(mTopic);
            MessageBean mb = new MessageBean();
            mb.channelId = mTopic;
            mb.operationStyle = MqttConstant.OFF_GROUP;
            EventBus.getDefault().post(mb);
            //删除topic表中的数据
            DatabaseManager.getInstance().deleteTopic(ctx, mTopic, sp.getString(MqttConstant.USERID, ""));
        }
    }

    /**
     * 处理聊天消息
     *
     * @param topic   聊天的topic
     * @param message 聊天的消息
     * @throws Exception
     */
    private void handleChatMessage(final String topic, String message) throws Exception {

        final MessageBean mb = JSONObject.parseObject(message, MessageBean.class);

        //是我自己发送的消息,已经存储在数据库中了,但是需要把isReach状态改为SUCCESS状态
        if (sp.getString(MqttConstant.USERID, "").equals(mb.sendId)) {
            DatabaseManager.getInstance().updateReachStatus(ctx, mb.sendDate, MqttConstant.MESSAGE_SEND_SUCCESS
                    , mb.sendId, topic);
            //把送达状态修改为已送达
            mb.receiverTime = System.currentTimeMillis() + "";
            mb.channelId = topic;
            mb.isReach = MqttConstant.MESSAGE_SEND_SUCCESS;
            noticePageUpdate(mb);
            return;
        }

        //过滤重复消息
        if (DatabaseManager.getInstance().hasReceived(ctx, topic, mb.sendDate, mb.sendId, sp.getString(MqttConstant.USERID, ""))) {
            Log.e(TAG, " === 重复消息 === " + mb.content);
            return;
        }

        mb.receiverTime = System.currentTimeMillis() + "";
        mb.channelId = topic;
//        mb.chatType = getChatType(topic);

//        if (MqttConstant.MQTTMESSAGENOTICE.equals(mb.messageType)) {
//            //增删群成员,群头像和群昵称可能会发生变化,需修改群信息(存在sp中的信息)
//            //添加订阅信息, 内存中 和 sp 中都添加
//            updateInfo(topic, mb.receivePic, mb.receiveName);
//        }

//        //群聊的话,更新头像
//        if (topic.startsWith(MqttConstant.START_GROUP) || topic.startsWith(MqttConstant.START_CHILD))
//
//            if (MqttConstant.topicMap != null) {
//
//                TopicBean topicBean = MqttConstant.topicMap.get(topic);
//                if (topicBean != null) {
//                    mb.receivePic = topicBean.topicImg;
//                    mb.receiveName = topicBean.topicName;
//                }
//
//            }

        switch (mb.messageType) {

//            case MqttConstant.MQTTMESSAGENOTICE: //创建群  加人 删人
//
//                //消息 声音和铃声震动
//                remainUser(topic);
//
//                //数据库存储消息
//                save2Table(mb, topic);
//
//                noticePageUpdate(mb);
//
//                break;

            case MqttConstant.MQTTMESSAGETEXT://纯文本

                //消息 声音和铃声震动
                remainUser(topic);
                save2Table(mb, topic);
                noticePageUpdate(mb);

                break;

            case MqttConstant.MQTTMESSAGEPHOTO: //图片

                String url = mb.content;

                //存储图片
                final String picPath = getHintFile() + "/" + UUID.randomUUID().toString() + ".jpg";

                receivePic(mb, picPath, topic);//先保存图片,防止重复消息时 子线程插入太慢 造成消息重复

                RetrofitHttpUtil.getInstance().downloadPicFromNet(new Observer<Bitmap>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                    }

                    @Override
                    public void onNext(Bitmap bp) {

                        try {
                            if (bp != null)
                                CommonUtils.saveBitmap2Local(bp, picPath);

                            //消息 声音和铃声震动
                            remainUser(topic);

                            noticePageUpdate(mb);

                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        //因为加载图片有延迟, 所以在这里再更新下
                        if (isTopActivity()) {
                            EventBus.getDefault().post(MqttConstant.UPDATE_RED_COUNT);
                        }

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                }, url);

                break;

            case MqttConstant.MQTTMESSAGEVOICE://语音

                //消息 声音和铃声震动
                remainUser(topic);

                // 先把语音保存到本地,再存储到数据库
                String videoPath = getHintFile() + "/" + UUID.randomUUID().toString() + ".amr";

                //存储语音文件
                File2Code.decoderBase64File(mb.content, videoPath);
//                    Log.d(TAG, "音频存储路径:" + videoPath);
                mb.content = videoPath;
                save2Table(mb, topic);
                noticePageUpdate(mb);

                break;

        }

        //判断homeactivity是否在顶部, 让homeactivity 更新小红点个数
        if (isTopActivity()) {
            EventBus.getDefault().post(MqttConstant.UPDATE_RED_COUNT);
        }

    }

    private void noticePageUpdate(MessageBean mb) {
        mb.operationStyle = MqttConstant.RECEIVE_MESSAGE;
        EventBus.getDefault().post(mb); //通知有新消息 (chatfragment页面 chatactivity页面)
    }

    private void receivePic(MessageBean mb, String picPath, String topic) {

        mb.content = picPath;
        save2Table(mb, topic);

    }

//    /**
//     * 更新群聊的信息
//     *
//     * @param topic  群聊的topic
//     * @param imgUrl 群聊的url
//     * @param name   群聊的昵称
//     */
//    private void updateInfo(String topic, String imgUrl, String name) {
//
//        if (MqttConstant.topicMap == null)
//            MqttConstant.topicMap = (Map<String, TopicBean>) JSON.parse(sp.getString(MqttConstant.TOPIC_MAP, ""));
//
//        TopicBean tb = new TopicBean();
//        tb.topic = topic;
//        tb.topicImg = imgUrl;
//        tb.topicName = name;
//        MqttConstant.topicMap.put(topic, tb);
//
//        sp.edit().putString(MqttConstant.TOPIC_MAP, JSON.toJSONString(MqttConstant.topicMap, true)).apply();
//
//    }

    /**
     * 发出震动和声音提醒
     */
    private void remainUser(String topic) {

        //如果设置消息不提醒 就返回
        if (!sp.getBoolean(Constant.IS_NOTICE, true)) {
            return;
        }

        //先判断手机是否是关闭了提示音
        AudioManager mAudioManager = (AudioManager) ctx.getSystemService(Context.AUDIO_SERVICE);
        int streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION);

        int ringerMode = mAudioManager.getRingerMode();

//        int ringerModeNormal = AudioManager.RINGER_MODE_NORMAL;// 正常模式,有声,是否震动取决于原来系统声音设置中振动的设置
//AudioManager.RINGER_MODE_SILENT 静音模式,无声不震
        //AudioManager.RINGER_MODE_VIBRATE 震动模式,无声,震动

        Set<String> remaindSet = sp.getStringSet(MqttConstant.REMAIND + sp.getString(MqttConstant.USERID, ""), null);

//        Log.d(TAG, "需要消息提醒? :" + remaindSet.toString());

        if (!(remaindSet != null && remaindSet.contains(topic))) {//需要提醒

            //是否需要声音提醒
            if (streamVolume > 0) {

                if (soundPool == null || loadId == 0) {
                    soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
                    loadId = soundPool.load(ctx, R.raw.gl, 1);
//            loadId = soundPool.load(ctx, R.raw.notificationsound, 1);

                    soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
                        @Override
                        public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
                            soundPool.play(loadId, 1, 1, 0, 0, 1);
                        }
                    });

                } else {// ==0表示加载失败, 否则表示加载成功
                    soundPool.play(loadId, 1, 1, 0, 0, 1);
                }

            }

            if (AudioManager.RINGER_MODE_SILENT != ringerMode) {

                //震动提醒
                if (vibrator == null)
                    vibrator = (Vibrator) ctx.getSystemService(Service.VIBRATOR_SERVICE);
//                Log.e(TAG, "震动吗 ： " + AudioManager.RINGER_MODE_SILENT + ",震动模式：" + ringerMode);
                vibrator.vibrate(500);
            }

        }

    }

    @NonNull
    private String getHintFile() {

        String cacheDirHint = Environment.getExternalStorageDirectory().getPath() + MqttConstant.PHOTO_PATH_HINT;

        File photoHint = new File(cacheDirHint);

        if (!photoHint.exists()) {//创建隐藏文件夹
            photoHint.mkdirs();

            //再创建 .nomedia 文件nomedia
            File noMedia = new File(cacheDirHint + ".nomedia");
            if (!noMedia.exists()) {
                try {
                    noMedia.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else noMedia = null;

        }
        return cacheDirHint;
    }

    /**
     * 保存数据到数据库
     *
     * @param topic
     */
    private void save2Table(MessageBean mb, String topic) {

        if (mb == null)
            return;

        Log.d(TAG, " 保存聊天消息到数据库  " + Thread.currentThread().getName());

        //往历史记录表里插入 聊天记录
        DatabaseManager.getInstance().insertHisData(ctx, new Object[]{mb.sendId, mb.sendName, mb.sendPic, mb.receiverTime,
                "0", mb.content, topic, mb.messageType, mb.receiveId, mb.receiveName, mb.receivePic,
                mb.voiceLength, mb.chatType, mb.sendDate, sp.getString(MqttConstant.USERID, ""), MqttConstant.UNLISTENER, MqttConstant.MESSAGE_SEND_SUCCESS});

        //往最新的topic表中插入数据
//        int count

//        if (CommonUtils.isGroupChat(topic)) {//群聊

//            if (TextUtils.isEmpty(mb.receiveName)) { //如果没有群昵称等信息

        mb.isRead = DatabaseManager.getInstance().updateTopicWithoutInfo(ctx, new String[]{mb.sendId, mb.sendName,
                mb.sendPic, mb.receiverTime, mb.content,
                mb.messageType, mb.voiceLength + "", mb.chatType + "", mb.sendDate + "", "1", topic, sp.getString(MqttConstant.USERID, "")});

//            } else { //有群昵称  群头像等信息
//
////                    topicName, sendId, sendName, sendPic, receiverTime, receiveId" +
////                ",content ,messageType,voiceLength,chatType,sendTime,receivePic, receiveName, isListener, isRead, topic, userId
//
//                count = DatabaseManager.getInstance().updateTopic(ctx, new String[]{mb.receiveName, mb.sendId, mb.sendName,
//                        mb.sendPic, mb.receiverTime, mb.receiveId, mb.content,
//                        mb.messageType, mb.voiceLength + "", mb.chatType + "", mb.sendDate + "", mb.receivePic,
//                        mb.receiveName, MqttConstant.UNLISTENER + "", "1", topic, sp.getString(MqttConstant.USERID, "")});
//            }

//        } else { //私聊
//
//            count = DatabaseManager.getInstance().updateTopic(ctx, new String[]{mb.sendName, mb.sendId, mb.sendName,
//                    mb.sendPic, mb.receiverTime, sp.getString(MqttConstant.USERID, ""), mb.content,
//                    mb.messageType, mb.voiceLength + "", mb.chatType + "", mb.sendDate + "",
//                    sp.getString(Constant.USER_IMG, ""), sp.getString(Constant.NICKNAME, ""), MqttConstant.UNLISTENER + "",
//                    "1", topic, sp.getString(MqttConstant.USERID, "")});
//        }
//        mb.isRead = count;

    }

    private boolean isTopActivity() {
        boolean isTop = false;
        ActivityManager am = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
        ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
        if (cn.getClassName().equals(HomeActivity.class.getName())) {
            isTop = true;
        }
        return isTop;
    }

}
